<template>
    <div class="white-box-form">
        <el-form
            ref="ruleRef"
            :disabled="isDetails"
            :model="state.ruleForm"
            :rules="state.rules"
            label-width="120px"
            class="mt-20"
        >
            <el-form-item label="网点名称" prop="outletsName">
                <el-input
                    v-model.trim="state.ruleForm.outletsName"
                    clearable
                    placeholder="请输入网点名称"
                />
            </el-form-item>
            <el-form-item label="网点联系人" prop="outletsMember">
                <el-input
                    v-model.trim="state.ruleForm.outletsMember"
                    clearable
                    placeholder="请输入网点联系人"
                />
            </el-form-item>
            <el-form-item label="网点联系电话" prop="outletsPhone">
                <el-input
                    v-model.trim="state.ruleForm.outletsPhone"
                    clearable
                    maxlength="11"
                    placeholder="请输入网点联系电话"
                />
            </el-form-item>
            <el-form-item label="网点位置" prop="location">
                <div class="flex items-end">
                    <!-- 地图 -->
                    <Teleport
                        :to="enlargeMap"
                        :disabled="state.disabledTeleport"
                    >
                        <TencentMap
                            ref="mapRef"
                            :search="state.isEnlargeMap"
                            :map-class="
                                !state.isEnlargeMap ? 'h-250 w-450' : ''
                            "
                            :multiOptions="{
                                polygon: true,
                                circle: true,
                                editor: state.isEnlargeMap,
                                overlayList: state.mapType
                                    ? ['polygon', 'circle']
                                    : ['marker'],
                            }"
                            :marker-geometries="state.marker"
                            :polygon-geometries="state.polygon"
                            :circle-geometries="state.circle"
                            @chooseSearchRes="chooseSearchRes"
                            @markerClick="markerClick"
                            @clickTool="onClickTool"
                        >
                            <template #search>
                                <el-button
                                    class="ml-auto"
                                    type="primary"
                                    @click="confirmChoose"
                                    >确定</el-button
                                >
                            </template>
                            <template v-if="state.mapType" #mapTop>
                                <div
                                    class="bg-#e2f0ff p-5 pl-10 mb-5 color-coolGray"
                                >
                                    <p class="mb-5">
                                        多边形：1.点击多边形图标&nbsp;&nbsp;2.依次点击地图选择范围&nbsp;&nbsp;3.双击自动合并起点与终点，完成绘制
                                    </p>
                                    <p>
                                        圆形：1.点击圆形图标&nbsp;&nbsp;2.点击地图选择中心点&nbsp;&nbsp;3.移动鼠标选择范围&nbsp;&nbsp;4.双击完成绘制
                                    </p>
                                </div>
                            </template>
                        </TencentMap>
                    </Teleport>
                    <el-button
                        class="ml-5"
                        plain
                        type="primary"
                        @click="openMap(0)"
                        >选择网点位置</el-button
                    >
                </div>
            </el-form-item>
            <el-form-item label="网点详细地址" prop="fullAddress">
                <p class="mr-5">{{ state.ruleForm.wardAddress }}</p>
                <el-input
                    v-model.trim="state.ruleForm.fullAddress"
                    clearable
                    placeholder="街道、小区、写字楼、门牌号等"
                />
            </el-form-item>

            <el-form-item label="服务范围类型" prop="serviceRangeType">
                <el-radio-group
                    v-model="state.ruleForm.serviceRangeType"
                    @change="changeServiceType"
                >
                    <el-radio
                        v-for="item in state.outletsTypeList"
                        :key="item.value"
                        :value="item.value"
                        :disabled="item._disabled"
                        >{{ item.name }}</el-radio
                    >
                </el-radio-group>
            </el-form-item>

            <!-- 按区域 -->
            <el-form-item
                v-if="state.ruleForm.serviceRangeType === 0"
                label="网点服务范围"
                prop="regionDistrictCode"
            >
                <div v-if="!state.districtCodeShow">
                    <el-tag
                        v-for="item in state.ruleForm?.regionDistrictCodeInfo"
                        :key="item.code"
                        class="mr-10"
                        type="info"
                        >{{ item.fullName }}</el-tag
                    >
                </div>
                <el-cascader
                    v-if="state.districtCodeShow"
                    v-model="state.ruleForm.regionDistrictCode"
                    :options="regionData"
                    collapse-tags
                    filterable
                    :disabled="
                        state.disabledOutletsTypes.includes(
                            state.ruleForm.serviceRangeType
                        )
                    "
                    :props="regionCodeProps"
                    class="mr-10"
                    placeholder="请选择网点服务范围"
                />
                <el-button
                    v-if="showDistrictCodeBtn"
                    type="primary"
                    size="small"
                    plain
                    @click="changeSelectShow"
                    >重新选择</el-button
                >
                <el-button
                    v-if="isEdit && state.districtCodeShow"
                    type="primary"
                    size="small"
                    plain
                    @click="cancelReSelect"
                    >取消重选</el-button
                >
            </el-form-item>
            <!-- 按电子围栏 -->
            <el-form-item
                v-if="state.ruleForm.serviceRangeType === 10"
                label="网点服务范围"
                prop="electronicfenceLatitudeLongitude"
            >
                <el-button
                    plain
                    type="primary"
                    :disabled="
                        state.disabledOutletsTypes.includes(
                            state.ruleForm.serviceRangeType
                        )
                    "
                    @click="openMap(1)"
                    >选择电子围栏范围</el-button
                >
            </el-form-item>
            <el-form-item label="网点logo" prop="logoUrl">
                <el-upload
                    ref="uploadRef"
                    v-model:file-list="fileList"
                    v-loading="imgLoading"
                    :limit="1"
                    :class="{
                        'hide-upload-btn': state.ruleForm.logoUrl,
                    }"
                    :action="actionImgUrl()"
                    :http-request="uploadImg"
                    list-type="picture-card"
                    :on-remove="handleRemove"
                    :before-upload="beforeAvatarUpload"
                    :on-change="fileChange"
                    :on-preview="handlePreview"
                    :on-exceed="handleExceed"
                >
                    <el-icon color="#999">
                        <upload-filled />
                    </el-icon>
                </el-upload>
            </el-form-item>
            <el-form-item v-if="!isEdit" label="上级网点" prop="parentTreeCode">
                <el-tree-select
                    v-model="state.ruleForm.parentTreeCode"
                    :data="state.outletsOptions"
                    filterable
                    check-strictly
                    placeholder="请选择上级网点"
                    clearable
                    :props="{ value: 'treeCode', label: 'outletsName' }"
                />
                <div class="input-tips">
                    添加<code>子网点</code>时需选择上级网点。
                </div>
            </el-form-item>
            <!-- <el-form-item label="网点员工" prop="userSid">
                <select-load-more
                    v-model:selectValue="state.ruleForm.userSid"
                    v-model:options="state.userOptions"
                    v-model:needFilterOptions="state.needFilterUserOptions"
                    value="sid"
                    label="nickName"
                    placeholder="请选择网点员工"
                    multiple
                    popper-class="user-select"
                    :apiFun="getUserOptions"
                />
            </el-form-item> -->
            <el-form-item label="备注" prop="note">
                <el-input
                    v-model.trim="state.ruleForm.note"
                    type="textarea"
                    maxlength="100"
                    :autosize="{ minRows: 2 }"
                    clearable
                    show-word-limit
                    placeholder="请输入备注"
                />
            </el-form-item>
            <el-form-item label="显示顺序" prop="viewSort">
                <el-input-number
                    v-model="state.ruleForm.viewSort"
                    :min="0"
                    :precision="0"
                    step-strictly
                />
            </el-form-item>
            <el-form-item label="状态" prop="status">
                <el-radio-group v-model="state.ruleForm.status">
                    <el-radio
                        v-for="item in state.statusList"
                        :key="item.memberKey"
                        :value="item.memberKey"
                        >{{ item.memberName }}</el-radio
                    >
                </el-radio-group>
            </el-form-item>
        </el-form>

        <div class="foot-btn">
            <el-button
                type="primary"
                :loading="state.form_loading"
                @click="submitForm(ruleRef)"
            >
                {{ isEdit ? "修改" : "添加" }}
            </el-button>
        </div>
        <go-back />
    </div>

    <!-- 地图放大选择 -->
    <el-dialog
        v-model="state.isEnlargeMap"
        title="网点信息"
        width="60%"
        top="5vh"
        @open="panToCenter"
        @close="closeMap"
        @closed="panToCenter"
    >
        <div ref="enlargeMap"></div>
    </el-dialog>

    <!-- 图片预览 -->
    <el-dialog v-model="imgVisible">
        <img w-full :src="dialogImageUrl" />
    </el-dialog>
</template>

<script setup>
import { inject, ref, onMounted, reactive, nextTick, computed } from "vue";
import { useRouter, useRoute } from "vue-router";
import GoBack from "@components/GoBack.vue";
import { validPhone } from "@/assets/common/utils";
import { watch } from "vue";
import { regionData } from "element-china-area-data";
import UploadImg from "@/mixins/upload-img";
import selectLoadMore from "@/components/selectLoadMore.vue";
import {
    getOutletDetail,
    getOutletsAll,
    getOutletDistrictCodes,
    getOutletElectronics,
    addOutlet,
    editOutlet,
    getOutletUsers,
} from "@/apis/outlet/outlet";
import { getUserDetail as getUserDetailApi, getUsers } from "@/apis/user/user";
import { getConfigsByType, getOrderConfigs } from "@/apis/order/config.js";
import TencentMap from "@/components/TencentMap.vue";
import { useDictStore } from "@stores/dict.js";

const dictStore = useDictStore();
dictStore.getDictMembers("data_status").then((res) => (state.statusList = res));

const router = useRouter();
const route = useRoute();

const $message = inject("$message");
const imgUrl = inject("imgUrl");

const sid = route.query.sid;
const isEdit = ref(false);
const isDetails = ref(false);
const form_loading = ref(false);
const ruleRef = ref(null);
const mapRef = ref(null);
const enlargeMap = ref(null);
const regionCodeProps = {
    multiple: true,
    emitPath: false,
};
const state = reactive({
    statusList: [],
    outletsTypeList: [],
    ruleForm: {
        outletsName: null,
        outletsMember: null,
        outletsPhone: null,
        serviceRangeType: null,
        electronicfenceLatitudeLongitude: [], // 网点服务范围-按电子围栏
        regionDistrictCode: [], // 网点服务范围-按区划
        latitude: null, // 经度
        longitude: null, // 纬度
        wardAddress: null,
        fullAddress: null,
        districtCode: null,
        userSid: [],
        parentTreeCode: null,
        logoUrl: null,
        note: null,
        viewSort: 0,
        status: 0,
        location: null, // 经纬度对象
    },
    rules: {
        outletsName: [
            { required: true, message: "请输入网点名称", trigger: "blur" },
        ],
        logoUrl: [
            { required: true, message: "请上传网点logo", trigger: "blur" },
        ],
        outletsMember: [
            { required: true, message: "请输入网点联系人", trigger: "blur" },
        ],
        location: [
            { required: true, message: "请选择网点位置", trigger: "blur" },
        ],
        fullAddress: [
            { required: true, message: "请填写网点具体地址", trigger: "blur" },
        ],
        outletsPhone: [
            { required: true, validator: validPhone, trigger: "blur" },
        ],
        serviceRangeType: [
            { required: true, message: "请选择服务范围类型", trigger: "blur" },
        ],
        regionDistrictCode: [
            { required: true, message: "请选择网点服务范围", trigger: "blur" },
        ],
        electronicfenceLatitudeLongitude: [
            { required: true, message: "请选择网点服务范围", trigger: "blur" },
        ],
    },
    outletsOptions: [],
    userOptions: [],
    needFilterUserOptions: [],
    disabledOutletsTypes: [], // 被禁用的网点类型
    mapType: null, // 0 选择位置 1 选择电子围栏
    isEnlargeMap: false, // 电子围栏地图是否放大
    disabledTeleport: true,
    marker: [],
    polygon: [],
    circle: [],
    districtCodeShow: true,
});

const showDistrictCodeBtn = computed(() => {
    return (
        isEdit.value &&
        !state.districtCodeShow &&
        state.ruleForm?.regionDistrictCodeInfo.length
    );
});

onMounted(async () => {
    if (/Edit$/.test(route.name)) {
        isEdit.value = true;
    }
    getOutletsOptions();
    getOutletsTypeOptions();
    if (sid) {
        await getDetail();
    }

    initMap();
});

const getDetail = async () => {
    const res = await getOutletDetail({ sid });

    if (res.data.code == 200) {
        state.ruleForm = res.data.data;
        // 处理图片
        if (state.ruleForm.logoUrl) {
            const arr = state.ruleForm.logoUrl.split("/");
            fileList.value.push({
                name: arr[arr.length - 1],
                url: imgUrl + state.ruleForm.logoUrl,
            });
        }
        // 获取网点位置
        const { latitude, longitude } = state.ruleForm;
        if (latitude && longitude) {
            state.ruleForm.location = new TMap.LatLng(latitude, longitude);
        }
        // 根据网点服务类型查询对应信息
        if (state.ruleForm.serviceRangeType === 0) {
            // 按区域
            getRegionCode();
        } else {
            // 按电子围栏
            await getElectronicFence();
        }
        // 获取员工
        getStaff();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

// 分页获取用户信息
const getUserOptions = async (params) => {
    const res = await getUsers({
        ...params,
        nickName: params.keyword,
    });
    if (res.data.code == 200) {
        return res;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

// 获取所有网点
const getOutletsOptions = async () => {
    const res = await getOutletsAll();
    if (res.data.code == 200) {
        state.outletsOptions = res.data.data;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getOutletsTypeOptions = async () => {
    const res = await getConfigsByType({ type: 2 });
    if (res.data.code == 200) {
        state.outletsTypeList = res.data.data;
        getOutletsConfiguredTypeOptions();
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

// 获取已配置的网点类型
const getOutletsConfiguredTypeOptions = async () => {
    const res = await getOrderConfigs({ type: 2 });
    if (res.data.code == 200) {
        const configureds = res.data.data.map((item) => item.value);
        state.disabledOutletsTypes = [];
        state.outletsTypeList.forEach((item) => {
            if (!configureds.includes(item.value)) {
                item._disabled = true;
                state.disabledOutletsTypes.push(item.value);
            }
        });
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const getUserDetail = async (sid) => {
    const res = await getUserDetailApi({ sid });
    if (res.data.code == 200) {
        return res.data.data;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

// 根据网点SID查询网点服务的行政区划编码
const getRegionCode = async () => {
    const res = await getOutletDistrictCodes({ sid });
    if (res.data.code == 200) {
        state.ruleForm.regionDistrictCode = res.data.data.map(
            (item) => item.regionDistrictCode
        );
        state.ruleForm.regionDistrictCodeInfo = res.data.data;
        state.districtCodeShow = false;
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

const changeSelectShow = () => {
    state.districtCodeShow = true;
    state.ruleForm.regionDistrictCode = [];
};

const cancelReSelect = () => {
    state.districtCodeShow = false;
    state.ruleForm.regionDistrictCode =
        state.ruleForm.regionDistrictCodeInfo.map(
            (item) => item.regionDistrictCode
        );
};

// 根据网点SID查询网点服务的电子围栏坐标
const getElectronicFence = async () => {
    const res = await getOutletElectronics({ sid });

    if (res.data.code == 200) {
        if (res.data.data) {
            // 字符串转数组
            state.ruleForm.electronicfenceLatitudeLongitude =
                res.data.data.reduce((pre, item) => {
                    if (item.electronicfenceType === 0) {
                        // 多边形
                        item.polygonCoordinate = item.polygonCoordinate.reduce(
                            (pre, cur) => {
                                pre.push(...cur);
                                return pre;
                            },
                            []
                        );
                    } else {
                        // 圆形
                        item.circleRadius = Number(item.circleRadius);
                    }
                    pre.push(item);
                    return pre;
                }, []);
            console.log(state.ruleForm.electronicfenceLatitudeLongitude);
        }
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

// 根据网点sid查询绑定的员工
const getStaff = async () => {
    const res = await getOutletUsers({ sid });
    if (res.data.code == 200) {
        const users = res.data.data;
        state.ruleForm.userSid = [];
        users.forEach((item) => {
            state.ruleForm.userSid.push(item.sid);
            state.userOptions.push(item);
            state.needFilterUserOptions.push(item);
        });
    } else {
        $message({ message: res.data.msg, type: "error" });
    }
};

// 初始化地图
const initMap = () => {
    mapRef.value.initMap();
    // 网点位置
    mapRef.value.panTo(state.ruleForm.location);
    // 图形数据
    state.marker = getMarkerGeometries();
    state.polygon = getPolygonGeometries();
    state.circle = getCircleGeometries();
};

// 设置点标记
const setMarker = (latLng) => {
    state.marker = [
        {
            position: latLng,
        },
    ];
};

// 初始化点
const getMarkerGeometries = () => {
    let geometries = [];

    if (state.ruleForm.location) {
        geometries.push({
            position: state.ruleForm.location,
        });
    }

    return geometries;
};

// 初始化多边形 多边形paths数组每一项转 LatLng
const getPolygonGeometries = () => {
    let geometries = [];
    if (state.ruleForm.electronicfenceLatitudeLongitude) {
        geometries = state.ruleForm.electronicfenceLatitudeLongitude
            .filter((item) => item.electronicfenceType === 0)
            .map((item) => {
                return { paths: item.polygonCoordinate };
            });
        geometries.forEach((geo) => {
            geo.paths = geo.paths.reduce((pre, item, index, arr) => {
                if (index % 2 === 1) {
                    pre.push(new TMap.LatLng(arr[index - 1], item));
                }
                return pre;
            }, []);
        });
    }
    return geometries;
};

// 初始化圆形 多边形paths数组每一项转 LatLng
const getCircleGeometries = () => {
    let geometries = [];
    if (state.ruleForm.electronicfenceLatitudeLongitude) {
        geometries = state.ruleForm?.electronicfenceLatitudeLongitude
            .filter((item) => item.electronicfenceType === 1)
            .map((item) => {
                return {
                    center: new TMap.LatLng(
                        item.circleCoordinate[0],
                        item.circleCoordinate[1]
                    ),
                    radius: item.circleRadius,
                };
            });
    }
    return geometries;
};

// 开启放大地图
const openMap = (type) => {
    state.mapType = type;
    state.isEnlargeMap = true;
    nextTick(() => {
        state.disabledTeleport = false;
    });
};

// 关闭地图对话框
const closeMap = () => {
    // 取消选中工具
    mapRef.value.cancelSelectedTool();
    state.isEnlargeMap = false;
    state.mapType = null;
    state.disabledTeleport = true;

    // 图形数据
    state.marker = getMarkerGeometries();
    state.polygon = getPolygonGeometries();
    state.circle = getCircleGeometries();
};

// 地图移动到中心点
const panToCenter = () => {
    mapRef.value.panTo(state.ruleForm.location);
};

// 选择位置
const markerClick = (e) => {
    setMarker(e.latLng);
};

const onClickTool = ({ tool, stop }) => {
    switch (tool) {
        case "polygon":
            if (mapRef.value.getCircle().geometries.length) {
                stop();
                $message({ message: "只能选择一种图形", type: "warning" });
            }
            break;
        case "circle":
            if (mapRef.value.getPolygon().geometries.length) {
                stop();
                $message({ message: "只能选择一种图形", type: "warning" });
            }
            break;
    }
};

// 确定选择
const confirmChoose = () => {
    // 取消选中工具
    mapRef.value.cancelSelectedTool();
    switch (state.mapType) {
        case 0:
            // 选择位置
            const location = mapRef.value.getMarker().geometries[0]?.position;
            if (location) {
                state.ruleForm.location = location;
                const geocoder = new TMap.service.Geocoder();
                geocoder.getAddress({ location }).then((res) => {
                    const {
                        address_component: {
                            province,
                            city,
                            district,
                            street,
                            street_number,
                        },
                        ad_info: { adcode },
                    } = res.result;
                    // 省市区
                    state.ruleForm.wardAddress = province + city + district;
                    // 具体位置
                    state.ruleForm.fullAddress = street + street_number;
                    // 行政区划编码
                    state.ruleForm.districtCode = adcode;
                });
            }
            break;
        case 1:
            // 选择电子围栏
            const electronicfenceLatitudeLongitude = [];
            // 多边形
            mapRef.value.getPolygon().geometries.forEach((geo) => {
                electronicfenceLatitudeLongitude.push({
                    electronicfenceType: 0,
                    polygonCoordinate: geo.paths.reduce((pre, path) => {
                        pre.push(path.lat, path.lng);
                        return pre;
                    }, []),
                });
            });
            // 圆形
            mapRef.value.getCircle().geometries.forEach((geo) => {
                electronicfenceLatitudeLongitude.push({
                    electronicfenceType: 1,
                    circleRadius: geo.radius,
                    circleCoordinate: [geo.center.lat, geo.center.lng],
                });
            });
            state.ruleForm.electronicfenceLatitudeLongitude =
                electronicfenceLatitudeLongitude;
            break;
    }
    closeMap();
};

watch(
    () => state.ruleForm.location,
    (newVal) => {
        state.ruleForm.latitude = newVal?.lat || null;
        state.ruleForm.longitude = newVal?.lng || null;
    },
    {
        deep: true,
    }
);

// 选择搜索地点
const chooseSearchRes = (e) => {
    setMarker(e.location.location);
};

// 切换服务范围类型 渲染/清除电子围栏
const changeServiceType = (e) => {
    if (e === 0) {
        // 按区域 清除
        state.polygon = [];
        state.circle = [];
    } else {
        // 按电子围栏 渲染
        state.polygon = getPolygonGeometries();
        state.circle = getCircleGeometries();
    }
};

const uploadRef = ref(null);
const {
    succList,
    imgLoading,
    handlePreview,
    actionImgUrl,
    uploadImg,
    handleRemove,
    beforeAvatarUpload,
    fileChange,
    handleExceed,
    imgVisible,
    dialogImageUrl,
    fileList,
} = UploadImg();
watch(
    succList,
    (newVal) => {
        state.ruleForm.logoUrl = newVal.length ? newVal[0] : "";
    },
    { deep: true }
);

// 提交表单
const submitForm = (formEl) => {
    if (!formEl) return;
    formEl.validate(async (valid, fields) => {
        if (valid) {
            form_loading.value = true;
            const form = JSON.parse(JSON.stringify(state.ruleForm));

            // 电子围栏参数转字符串
            if (form.serviceRangeType === 10) {
                form.electronicfenceLatitudeLongitude.forEach((item) => {
                    if (item.electronicfenceType === 0) {
                        item.polygonCoordinate = `[${item.polygonCoordinate.toString()}]`;
                    } else {
                        item.circleCoordinate = `[${item.circleCoordinate.toString()}]`;
                        item.circleRadius = item.circleRadius.toString();
                    }
                });
            }
            // 过滤参数
            form.serviceRangeType === 0 &&
                delete form.electronicfenceLatitudeLongitude;
            form.serviceRangeType === 10 && delete form.regionDistrictCode;
            let res = null;
            if (isEdit.value) {
                res = await editOutlet(form);
            } else {
                res = await addOutlet(form);
            }
            form_loading.value = false;
            if (res.data.code == 200) {
                $message({
                    message: isEdit.value ? "修改成功" : "添加成功",
                    type: "success",
                });
                router.back();
            } else {
                $message({ message: res.data.msg, type: "error" });
            }
        }
    });
};
</script>

<style scoped lang="less"></style>
